package org.hxzon.tapestry5.components;

import java.util.ArrayList;
import java.util.List;

import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.annotations.AfterRender;
import org.apache.tapestry5.annotations.BeginRender;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.corelib.base.AbstractField;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.Request;
import org.hxzon.tapestry5.util.ValueIsSelected;
import org.hxzon.tapestry5.util.ValueLabel;

public class CheckboxGroup extends AbstractField {

    @Parameter(name = "value", required = true, allowNull = false)
    private List<Object> _value;

    @Parameter(name = "valueLabel")
    private ValueLabel<Object> _valueLabel;

    @Parameter(name = "selectAll", value = "true")
    private boolean _selectAll;

    @Parameter(name = "valueIsSelected")
    private ValueIsSelected<Object> _valueIsSelected;

    @Parameter(name = "readonly", value = "false")
    private boolean _readonly;

    @Parameter(name = "labelFirst", value = "false")
    private boolean _labelFirst;

    @Parameter(name = "class", defaultPrefix = BindingConstants.LITERAL)
    private String _itemClass;

    @Inject
    private Request _request;

    @BeginRender
    void begin(MarkupWriter writer) {

        String clientId = getClientId();
        String ctrlName = getControlName();
        int size = _value.size();
        for (int i = 0; i < size; i++) {
            String label = null;
            Object curValue = _value.get(i);

            if (_valueLabel != null) {
                label = _valueLabel.toLabel(curValue, i);
            } else {
                label = curValue.toString();
            }

            boolean checked = (_selectAll || (_valueIsSelected != null && _valueIsSelected.isSelected(curValue)));
            writeCheckbox(writer, (clientId + "_" + i), ctrlName, checked, i, label, _labelFirst, _itemClass);
        }// end for
    }

    private void writeCheckbox(MarkupWriter writer, String clientId, String ctrlName, boolean checked, int index, String label, boolean labelFirst, String itemClass) {
        boolean drawItem = itemClass != null;
        if (drawItem) {
            writer.element("span", "class", itemClass);
        }
        if (labelFirst) {
            writer.element("label", "for", clientId);
            writer.write(label);
            writer.end();
        }
        writer.element("input", "type", "checkbox", "name", ctrlName, "id", clientId, "checked", checked ? "checked" : null, "value", index, "disabled", _readonly ? "disabled" : null);
        writer.end();
        if (!labelFirst) {
            writer.element("label", "for", clientId);
            writer.write(label);
            writer.end();
        }
        if (drawItem) {
            writer.end();
        }
    }

    @AfterRender
    void after(MarkupWriter writer) {

    }

    @Override
    protected void processSubmission(String controlName) {

        String[] postedValues = _request.getParameters(controlName);
        if (postedValues == null || postedValues.length == 0) {
            _value.clear();
            return;
        }
        List<Object> result = new ArrayList<Object>();
        for (String postedValue : postedValues) {
            result.add(_value.get(Integer.valueOf(postedValue)));
        }
        _value.clear();
        _value.addAll(result);
    }

}